package com.huilan.base.esl.service.impl;

import cn.hutool.core.util.StrUtil;
import com.huilan.base.esl.api.ApiApi;
import com.huilan.base.esl.api.AppApi;
import com.huilan.base.esl.pojo.ApiResult;
import com.huilan.base.esl.pojo.ApiResultBuild;
import com.huilan.base.esl.pojo.po.api.ApiEnum;
import com.huilan.base.esl.pojo.po.api.ApiPo;
import com.huilan.base.esl.pojo.po.api.ChannelPo;
import com.huilan.base.esl.pojo.po.app.AppEnum;
import com.huilan.base.esl.pojo.po.app.AppPo;
import lombok.extern.slf4j.Slf4j;
import org.freeswitch.esl.client.transport.SendMsg;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
public class ApiImpl extends BaseImpl implements ApiApi {


    @Override
    public ApiResult api(ApiPo apiPo) {
        List<String> stringList = eslClient.getClient().sendAsyncApiCommand(apiPo.getName(), apiPo.getArg());
        return ApiResultBuild.success(stringList);
    }

    @Override
    public ApiResult apiAsync(ApiPo apiPo) {
        List<String> stringList = eslClient.getClient().sendAsyncApiCommand(apiPo.getName(), apiPo.getArg(),true);
        return ApiResultBuild.success(stringList.get(0));
    }

    @Override
    public ApiResult uuid_bridge(String uuidA, String uuidB) {
        return api(ApiPo.builder()
                .name(ApiEnum.uuid_bridge.name())
                .arg(uuidA+" "+uuidB)
                .build());
    }

    @Override
    public ApiResult uuid_bridgeAsync(String uuidA, String uuidB) {
        return apiAsync(ApiPo.builder()
                .name(ApiEnum.uuid_bridge.name())
                .arg(uuidA+" "+uuidB)
                .build());
    }

    @Override
    public ApiResult interceptAsync(String uuid, String user) {
        String command = StrUtil.format("originate user/{} &intercept({})",user,uuid);
        return ApiResultBuild.success(commandAsync(command));
    }

    @Override
    public ApiResult channelsList() {
        List<String> stringList = commandSync("show channels");
        List<ChannelPo> channelPos = transformShowChannel(stringList);
        return ApiResultBuild.success(channelPos);
    }

    private Map data2Map(String data){
        Map<String, String> map = new HashMap<>();
        data = data.replace("{", "")
                .replace("}", "")
                .replace("\\","");
        String[] split = data.split(",");
        for (String s:split) {
            String[] split1 = s.split("=");
            if (split1.length == 2){
                map.put(split1[0],split1[1]);
            }
        }
        return map;
    }


    public List<ChannelPo> transformShowChannel(List<String> stringList){
        if (stringList == null || stringList.size()<=1){
            return new ArrayList<>();
        }
        stringList.remove(0);
        stringList.remove(stringList.size()-1);

        return stringList.stream().map(s -> {

            int begin = s.indexOf("{");
            int end = s.indexOf("}");
            Map map = new HashMap();
            if (begin > -1 && end > -1) {
                String data = s.substring(begin, end+1);
                map = data2Map(data);
                s = s.replace(data, "data");
            }

            String[] split = s.split(",");
            return ChannelPo.builder()
                    .uuid(split[0])
                    .direction(split[1])
                    .created(split[2])
                    .created_epoch(split[3])
                    .name(split[4])
                    .state(split[5])
                    .cid_name(split[6])
                    .cid_num(split[7])
                    .ip_addr(split[8])
                    .dest(split[9])
                    .application(split[10])
                    .application_data(split[11])
                    .dialplan(split[12])
                    .context(split[13])
                    .read_codec(split[14])
                    .read_rate(split[15])
                    .read_bit_rate(split[16])
                    .write_codec(split[17])
                    .write_rate(split[18])
                    .write_bit_rate(split[19])
                    .secure(split[20])
                    .hostname(split[21])
                    .presence_id(split[22])
                    .presence_data(split[23])
                    .accountcode(split[24])
                    .callstate(split[25])
                    .callee_name(split[26])
                    .callee_num(split[27])
                    .callee_direction(split[28])
                    .call_uuid(split[29])
                    .sent_callee_name(split[30])
                    .sent_callee_num(split[31])
                    .initial_cid_name(split[32])
                    .initial_cid_num(split[33])
                    .initial_ip_addr(split[34])
                    .initial_dest(split[35])
                    .initial_dialplan(split[36])
                    .initial_context(split[37])
                    .channelMap(map)
                    .build();
        }).collect(Collectors.toList());
    }

}
